<!--
Copyright 2014 The Chromium Authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.
-->

<link rel="import" href="ct-results-comparison.html">

<polymer-element name="ct-results-detail" attributes="failure builder">
  <template>
    <style>
      :host {
        display: block;
      }
    </style>
    <template if="{{!_urlGroups.length}}">
      No results to display.
    </template>
    <template repeat="{{urlGroup in _urlGroups}}">
      <template if="{{urlGroup.urls[_kUnknownKind]}}">
        <ct-test-output type="{{urlGroup.type}}" url="{{urlGroup.urls[_kUnknownKind]}}" flex layout vertical></ct-test-output>
      </template>
      <template if="{{!urlGroup.urls[_kUnknownKind]}}">
        <ct-results-comparison type="{{urlGroup.type}}" expectedUrl="{{urlGroup.urls[_kExpectedKind]}}"
            actualUrl="{{urlGroup.urls[_kActualKind]}}" diffUrl="{{urlGroup.urls[_kDiffKind]}}" flex layout vertical></ct-results-comparison>
      </template>
    </template>
  </template>
  <script>
    Polymer({
      failure: null,
      // FIXME: Initializing builder gives a JS error. Presumably because
      // ct-results-by-builder sets builder="{{builders[selected]}}". But,
      // it seems wrong that the way the parent uses this element constrains
      // what the element can do. Polymer bug?
      // builder: '',

      _urlGroups: [],
      _kExpectedKind: results.kExpectedKind,
      _kActualKind: results.kActualKind,
      _kDiffKind: results.kDiffKind,
      _kUnknownKind: results.kUnknownKind,

      observe: {
        failure: '_update',
        builder: '_update',
      },

      _isStdioStep: function(result, step) {
        return result.actual == 'UNKNOWN' || step == 'compile';
      },

      _update: function() {
        if (!this.failure || !this.builder)
          return;

        // FIXME: If the types of groups doesn't change, then it'd be better to do this
        // update in place so that the user doesn't see a flicker.
        this._urlGroups = [];

        var result = this.failure.resultNodesByBuilder[this.builder];
        // FIXME: There's probably a less hacky way to check this.
        if (result.actual == 'FAIL' || this._isStdioStep(result, this.failure.step))
          this._updateUrls();
        else
          this._updateWebkitTestUrls();
      },

      _updateWebkitTestUrls: function() {
        var result = this.failure.resultNodesByBuilder[this.builder];
        var failureInfo = results.failureInfo(this.failure.testName, this.builder, result.actual);

        // FIXME: Move this logic to a proper model class so that the network requests this makes
        // can be easily mocked out in tests.
        results.fetchResultsURLs(failureInfo).then(function(resultsUrls) {
          var resultsUrlsByTypeAndKind = {};
          resultsUrls.forEach(function(url) {
              var resultType = results.resultType(url);
              if (!resultsUrlsByTypeAndKind[resultType])
                  resultsUrlsByTypeAndKind[resultType] = {};
              resultsUrlsByTypeAndKind[resultType][results.resultKind(url)] = url;
          });

          Object.keys(resultsUrlsByTypeAndKind, function(resultType, resultsUrlsByKind) {
            this._urlGroups.push({
              type: resultType,
              urls: resultsUrlsByKind,
            });
          }.bind(this));
        }.bind(this));
      },

      _updateUrls: function() {
        // FIXME: Along with _updateWebkitTestUrls, move this logic to a proper model class
        // so that the network requests this makes can be easily mocked out in tests.

        var result = this.failure.resultNodesByBuilder[this.builder];

        // FIXME: We only store build logs by the test name, not the testsuite.testname,
        // which means that two failing tests from different test suites conflict!
        var testPart = this._isStdioStep(result, this.failure.step) ? 'stdio' : this.failure.testName;
        // Fix url for parameterized gtests, e.g.: /2 -> _2.
        testPart = testPart.replace(/\/(\d+)$/, "_$1");
        var url = result.masterUrl +
            '/builders/' + encodeURIComponent(this.builder);

        // FIXME: Make failure groups aware of their own url
        if (this.failure.testName)
          url +=
            '/builds/' + result.lastFailingBuild +
            '/steps/' + this.failure.step +
            '/logs/' + testPart;

        var resultsUrlsByKind = {};
        resultsUrlsByKind[this._kUnknownKind] = url;

        this._urlGroups.push({
          type: results.kTextType,
          urls: resultsUrlsByKind,
        });
      },
    });
  </script>
</polymer-element>
